home *** CD-ROM | disk | FTP | other *** search
- #include "sview.h"
-
- char* firstString(int first, char* string)
- {
- char* str = string;
- for(int i = 0; i < first && str != NULL; i++)
- {
- str = strchr(str, '\n');
- if(str != NULL)
- str++;
- }
- return str;
- }
- ///////////////////////////
- ScrollView::ScrollView(loc start_pos, char* str, rect b, loc sc, int interv,
- int dir)
- {
- bnd = b;
- start = loc(0, 0); pos = start_pos; string = str;
- number_of_nl = nRet(string);
- scale = sc; interval = interv; direction = dir;
- findString = NULL;
- }
- ///////////////////////////
- void ScrollView::showCursor()
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- int sz;
- int size_y = interval
- * (sz = fnt->scaledtextsize("H!", scale.X, scale.Y).height())
- / 10 * pos.Y; // vertical position
- int sh = (interval - 10) / 2 * sz / 10;
- char* tmp = firstString(pos.Y + start.Y - 1, string); // the n-th string
-
- tmp += start.X; // visible part of tmp
- int size_x; // HP text width, pixels
-
- char* tmp1 = new char[pos.X + 1]; // temporary length
- strncpy(tmp1, tmp, pos.X - 1);
- tmp1[pos.X - 1] = '\0'; // 0-terminated string
- size_x = fnt->scaledtextsize(tmp1, scale.X, scale.Y).width();
- delete tmp1;
-
- moveto(size_x, size_y - sh);
-
- setwritemode(XOR_PUT);
- setlinestyle(SOLID_LINE, 1, 1);
- lineto(size_x, size_y - sh - sz);
- setwritemode(COPY_PUT);
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- curs = loc(size_x, size_y);
- }
- /////////////////////////
- int ScrollView::lineLen(int num)
- {
- char* str1 = firstString(num, string);
- char* str2 = firstString(1, str1);
- if(str2 == NULL)
- return strlen(str1);
- return str2 - str1;
- /* char* c = new char[str2 - str1 + 1];
- strncpy(c, str1, str2 - str1);
- c[str2 - str1] = '\0'; // 0-terminated string
- int l = strlen(c);
- delete c;
- return l;
- */ }
- /////////////////////////
- char* ScrollView::showString(char* str, loc scale,
- int mode)
- {
- char* s = strchr(str, '\n');
- if(s != NULL)
- {
- int new_pos = s - str;
- char c = str[new_pos];
- str[new_pos] = '\0';
- if(new_pos > start.X)
- drawscaledstr(*fnt, str + start.X, scale.X,
- scale.Y, mode, direction);
- str[new_pos] = c;
- return str + new_pos + 1;
- }
- if(strlen(str) > start.X)
- drawscaledstr(*fnt, str + start.X, scale.X,
- scale.Y, mode, direction);
- return NULL;
- }
- /////////////////////////
- void ScrollView::show(int first, int last, int mode, int shift)
- {
- char* str = firstString(first - 1, string);
-
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- int s_size = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
-
- int top = (first - start.Y - 1) * s_size;
- int sh = (interval - 10) / 2
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- if(first != last || shift > 0)
- curs.X = 0;
- else
- str += pos.X + shift - 1;
- struct viewporttype viewinfo;
- getviewsettings(&viewinfo);
- if(curs.X == 0)
- {
- setviewport(viewinfo.left - 3, viewinfo.top,
- viewinfo.right + 3, viewinfo.bottom, 1);
- }
- bar(curs.X, top, viewinfo.right - viewinfo.left + 7,
- top + s_size * (last - first + 1));
- setviewport(viewinfo.left, viewinfo.top, viewinfo.right,
- viewinfo.bottom, 1);
- moveto(curs.X, top - sh + s_size);
-
- for(int i = first; i <= last; i++)
- {
- if((str = showString(str, scale, mode)) == NULL)
- break;
- moveto(0, s_size * (i - start.Y + 1) - sh);
- }
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- }
- //////////////////////////
- int ScrollView::up(int jmp)
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- int ret = 1;
- hideCursor();
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- int view_h = bnd.height() / h;
- if(pos.Y > jmp)
- {
- pos.Y -= jmp;
- int len;
- if(len = lineLen(pos.Y + start.Y - 1) < pos.X + start.X)
- {
- pos.X = 1; start.X = len - 1;
- show(start.Y + 1, start.Y + bnd.height() / h);
- }
- }
- else
- {
- if((start.Y > jmp - 1) || (start.Y > view_h - 1))
- {
- if(start.Y > view_h - 1)
- {
- start.Y -= view_h;
- pos.Y = view_h - jmp + 1;
- }
- else // if(start.Y > jmp - 1)
- {
- pos.Y = start.Y - jmp + 1;
- start.Y = 0;
- }
- int len = lineLen(pos.Y + start.Y - 1);
- if(len < pos.X + start.X)
- {
- pos.X = 1; start.X = len - 1;
- }
- show(start.Y + 1, start.Y + 1 + bnd.height() / h);
- }
- else
- ret = 0;
- }
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
-
- return ret;
- }
- /////////////////////////////////
- int ScrollView::dn(int jmp)
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- int ret = 1;
- hideCursor();
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- int view_h = bnd.height() / h;
-
- if(pos.Y + jmp - 2 < view_h && start.Y + pos.Y + jmp - 2 < number_of_nl)
- {
- pos.Y += jmp;
- int len = lineLen(start.Y + pos.Y - 1);
- if(len < pos.X + start.X)
- {
- pos.X = 1; start.X = len ? len - 1 : 0;
- show(start.Y + 1, start.Y + 1 + bnd.height() / h);
- }
- }
- else
- {
- if((start.Y + view_h - 2 < number_of_nl)
- || (start.Y + pos.Y + jmp - 2 < number_of_nl))
- {
- if(start.Y + view_h - 2 < number_of_nl)
- {
- start.Y += view_h;
- pos.Y = 1;
- }
- else // if(start.Y + pos.Y + jmp - 1 < number_of_nl)
- {
- start.Y += jmp;
- }
- int len;
- if(len = lineLen(start.Y + pos.Y - 1) < pos.X + start.X)
- {
- pos.X = 1; start.X = len - 1;
- }
- show(start.Y + 1, start.Y + 1 + bnd.height() / h);
- }
- else
- ret = 0;
- }
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- return ret;
- }
- /////////////////////////////////
- int ScrollView::left(int jmp)
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
- int ret = 0;
- hideCursor();
-
- if(pos.X > jmp) // not leftmost position
- pos.X -= jmp;
- else // leftmost screen position
- {
- if(start.X > jmp - 1)
- {
- ret = 1;
- start.X -= jmp;
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- show(start.Y + 1, start.Y + 1 + bnd.height() / h);
- }
- }
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- return ret;
- }
- ////////////////////////
- char* ScrollView::getLine(int n)
- {
- char* str = firstString(n, string);
- if(str == NULL)
- return NULL;
- char* str1;
- int len = ((str1 = firstString(1, str)) == NULL) ? strlen(str)
- : str1 - str - 1;
- char* c = new char[len + 5];
- strncpy(c, str, len);
- c[len] = '\0'; // 0-terminated string
- return c;
- }
- /////////////////////////
- int ScrollView::right(int jmp)
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
- int ret = 0;
- hideCursor();
- char* str = getLine(start.Y + pos.Y - 1); // current line
- if(start.X + pos.X + jmp - 2 // if we'll not leave this line
- < lineLen(start.Y + pos.Y - 1)) // after this jump
- {
- str[start.X + pos.X + jmp - 1] = '\0'; // NULL-terminates line
- int len = fnt->scaledtextsize(str + start.X, // length of visible
- scale.X, scale.Y).width(); // part, pixels
-
- if(bnd.width() > len) // not rightmost position
- pos.X += jmp;
- else // rightmost screen position
- {
- ret = 1;
- start.X += jmp;
- while(fnt->scaledtextsize(str + start.X,
- scale.X, scale.Y).width() > bnd.width())
- {
- start.X++;
- pos.X--;
- }
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- show(start.Y + 1, start.Y + 1 + bnd.height() / h);
- }
- }
- showCursor();
- delete str;
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- return ret;
- }
- ////////////////////////
- void ScrollView::home()
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- hideCursor();
- pos.X = 1;
- if(start.X != 0)
- {
- start.X = 0;
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- show(start.Y + 1, start.Y + 1 + bnd.height() / h);
- }
- start.X = 0;
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
-
- }
- ////////////////////////
- void ScrollView::end()
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- hideCursor();
- pos.X = 1;
- char* str = getLine(start.Y + pos.Y - 1);
- start.X = strlen(str);
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- show(start.Y + 1, start.Y + 1 + bnd.height() / h);
- showCursor();
- delete str;
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
-
- }
- ////////////////////////
- int ScrollView::pgUp()
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
- int ret = 1;
- hideCursor();
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- h = bnd.height() / h;
- if(h < start.Y)
- {
- start.Y -= h;
- pos.Y = 1;
- pos.X = 1;
- show(start.Y + 1, start.Y + 1 + h);
- }
- else
- ret = 0;
-
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- return ret;
- }
- /////////////////////////
- int ScrollView::pgDn()
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
- int ret = 1;
- hideCursor();
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- h = bnd.height() / h;
- char* str = firstString(start.Y + pos.Y - 1, string);
- int returns = nRet(str);
- if(h < returns)
- {
- start.Y += h;
- pos.X = 1;
- show(start.Y + 1, start.Y + 1 + h);
- }
- else
- ret = 0;
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
- return ret;
- }
- /////////////////////////
- void ScrollView::toTop()
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- hideCursor();
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- h = bnd.height() / h;
- start = loc(0, 0);
- pos = loc(1, 1);
- show(start.Y + 1, start.Y + 1 + h);
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
-
- }
- //////////////////////////
- void ScrollView::toBottom()
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- hideCursor();
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- h = bnd.height() / h;
- start = loc(0, nRet(string));
- pos = loc(1, 1);
- show(start.Y + 1, start.Y + h + 1);
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
-
- }
- ///////////////////////////
- int ScrollView::find(char* search)
- {
- setviewport(bnd.origin.X, bnd.origin.Y,
- bnd.corner.X, bnd.corner.Y, 1);
-
- int ret = 0; // find or not
- hideCursor();
- char* str = firstString(start.Y + pos.Y - 1, string); // start search position
- char* fnd = strstr(str + 1, search); // first
- if(fnd != NULL) // if search string
- { // presents
- int h = interval
- * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
- h = bnd.height() / h; // screen height, in HP intervals
- int y_pos = nRet(string) - nRet(fnd) + 1; // y pos of find string
- if(start.Y + h >= y_pos) // do not redraw screen
- pos.Y = y_pos - start.Y;
- else // redraw screen
- {
- start.Y = y_pos - 1;
- pos.Y = 1;
- }
-
- char* work = getLine(y_pos - 1); // line containing str
- char* work1 = firstString(y_pos - 1, string); // part of string
- int x_pos = fnd - work1; // distance from line beginning
- if(x_pos <= start.X) // redraw screen
- {
- start.X = x_pos;
- pos.X = 1;
- }
- else
- {
- work[x_pos] = '\0';
- if(fnt->scaledtextsize(work + start.X, scale.X, scale.Y).width()
- >= bnd.width()) // we are not in bnd
- {
- start.X = x_pos;
- pos.X = 1;
- }
- else // we are in bnd
- pos.X = x_pos - start.X;
- }
- ret = 1;
- delete work;
- show(start.Y + 1, start.Y + h + 1);
- }
-
- showCursor();
- setviewport(0, 0, getmaxx(), getmaxy(), 1);
-
- return ret;
- }
- /////////////////////////
- /*
-
- */
- /////////////////////////
-